package org.tema.ejb;

import java.sql.Date;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.tema.Priority;
import org.tema.Status;
import org.tema.Type;
import org.tema.entities.Product;
import org.tema.entities.TestCase;
import org.tema.entities.TestPlan;
import org.tema.entities.TestSpecification;
import org.tema.entities.User;

/**
 * Session Bean implementation class TestCaseBean
 */
@Stateless
public class TestCaseBean implements TestCaseBeanLocal {


	@PersistenceContext
	private EntityManager entityManager;
	
	@EJB
	ProductBeanLocal productBean;
	
	@EJB
	UserBeanLocal userBean;
	
	
	@EJB
	TestPlanBeanLocal planBean;
	
	@EJB
	TestSpecBeanLocal specificationBean;
	
	
    public TestCaseBean() {
     
    }
    //testCaseBean.addTestCase( this.getSearchWordSpec() , this.getSearchWordType(), this.getSearchWordStatus(), this.getSearchWordPriority(), this.getSummary(), this.getEnvironment(), this.getPreSteps(), this.getDescription(), this.getExpectedResult(), creationD, modificationD, this.getExecutionTime());
    public TestCase addTestCase( int bugId, String testSpecification, Type testType, Status testStatus, Priority testPriority, String summary, String environment, String preSteps, String description, String expectedResult, Date creationD, Date modificationD,double executionTime, String creatorName){
    	ArrayList<Integer> bugList;
    	TestCase testCase = new TestCase();
    	TestSpecification ts = specificationBean.findTestSpecBySummary(testSpecification);
    	Product p = ts.getProduct();
    	User currentUser = userBean.findUserByName(creatorName);
    	if( bugId != 0 ){
    		bugList = new ArrayList<Integer>();
    		bugList.add(bugId);
    		testCase.setBugId(bugList);
    	}
    	/*
    	else{
    		bugList = new ArrayList<Integer>();
    		bugList.add(0);
    		testCase.setBugId(bugList);
    	}
    	*/
    	testCase.setProduct(p);
    	testCase.setSpecification(ts);
    	testCase.setType(testType);
    	testCase.setStatus(testStatus);
    	testCase.setPriority(testPriority);
    	testCase.setSummary(summary);
    	testCase.setEnvironment(environment);
    	testCase.setPreSteps(preSteps);
    	testCase.setDescription(description);
    	testCase.setExpectedResult(expectedResult);
    	testCase.setCreationDate(creationD);
    	testCase.setModificationDate(modificationD);
    	testCase.setCreator(currentUser);
    	testCase.setExecutionTime(0);//all newly created test cases have actual execution times=0 because they're just created
		entityManager.persist(testCase);
		return testCase;
    }
    
    public TestCase addTestCase(  Priority testPriority, String summary, String env,  String pSteps, String description,  String expectedRes, int bugId, Type testType, Status testStatus,  Date cDate, Date mDate, String modifierName ){
    	ArrayList<Integer> bugList;
    	TestCase testCase = new TestCase();
    	User currentUser = userBean.findUserByName(modifierName);
    	testCase.setPriority(testPriority);
    	testCase.setSummary(summary);
    	testCase.setEnvironment(env);
    	testCase.setPreSteps(pSteps);
    	testCase.setDescription(description);
    	testCase.setExpectedResult(expectedRes);
    	if( bugId != 0 ){
    		bugList = new ArrayList<Integer>();
    		bugList.add(bugId);
    		testCase.setBugId(bugList);
    	}
    	/*
    	else{
    		bugList = new ArrayList<Integer>();
    		bugList.add(0);
    		testCase.setBugId(bugList);
    	}
    	*/
    	testCase.setType(testType);
    	testCase.setStatus(testStatus);
    	testCase.setCreationDate(cDate);
    	testCase.setModificationDate(mDate);
    	testCase.setCreator(currentUser);
    	testCase.setExecutionTime(0);//all newly created test cases have actual execution times=0 because they're just created
		entityManager.persist(testCase);
		return testCase;
    }
    
	public TestCase  updateTestCase(TestCase testCase, int bugId, String modifierName){
    	User currentUser = userBean.findUserByName(modifierName);
		testCase.setModifier(currentUser);
		ArrayList<Integer> bugList = testCase.getBugId();
		if(bugList!=null){
			bugList.add(bugId);
			testCase.setBugId(bugList);
		}else{
			ArrayList<Integer> bugList1 = new ArrayList <Integer>();
			bugList1.add(bugId);
			testCase.setBugId(bugList1);
		}
		
		entityManager.merge(testCase);
	    return testCase;
	}
	
	public TestCase undoTestCaseChanges(TestCase testCase){
	    entityManager.refresh(entityManager.merge(testCase));
	    return testCase;
	}
	
	public void deleteTestCase(TestCase testCase){	
		entityManager.remove(entityManager.merge(testCase));
	}

	@SuppressWarnings("unchecked")
	public Collection <TestCase> findAllTestCases(){
		Query query = entityManager.createQuery(" SELECT c FROM TestCase c ");
		return (Collection <TestCase>) query.getResultList();
	}
	
	//search TestCases 
	public TestCase findTestCaseById( int id ){
		Query query;
		TestCase tc;
		try{
			query = entityManager.createQuery(" SELECT c FROM TestCase c WHERE c.id = :id  ");
			query.setParameter("id", id);
			tc = ( TestCase ) query.getSingleResult();
		}
		catch (NoResultException e) {
			throw new IllegalArgumentException("no test case with id '" + id + "'");
		}
		return tc;
	}
	
	@SuppressWarnings("unchecked")
	public TestCase findTestCaseBySummary( String summary ){
		Query query;
		TestCase tc;
		try{
				//summary = summary.concat("%");
				query = entityManager.createQuery(" SELECT c FROM TestCase c WHERE c.summary = :summary  ");
				query.setParameter("summary", summary);
				tc = ( TestCase ) query.getSingleResult();
		}
		catch (NoResultException e) {
			throw new IllegalArgumentException("no test case with summary '" + summary + "'");
		}
		return  tc;
	}
	
	
	@SuppressWarnings("unchecked")
	public Collection <TestCase> findTestCasesBySummary( String summary ){
		Query query;
		Collection <TestCase> tc;
		summary = summary.concat("%");
		query = entityManager.createQuery(" SELECT c FROM TestCase c WHERE c.summary LIKE :summary  ");
		query.setParameter("summary", summary);
		tc = ( Collection <TestCase> ) query.getResultList();
		return  tc;
	}
	

	
	//search by test case type: SMOKE, BAT, REGRESSION
	@SuppressWarnings("unchecked")
	public  Collection <TestCase> findTestCaseByType( Type type ){
		Query query = entityManager.createQuery(" SELECT c FROM TestCase c WHERE c.type = :type  ");
		query.setParameter("type", type);
		return  ( Collection <TestCase> ) query.getResultList();
	}
	
	//search by test case priority: P0 .. P2
	@SuppressWarnings("unchecked")
	public  Collection <TestCase> findTestCaseByPriority( Priority p ){
		Query query = entityManager.createQuery(" SELECT c FROM TestCase c WHERE c.priority = :p  ");
		query.setParameter("p", p);
		return  ( Collection <TestCase> ) query.getResultList();
	}
	
	//search test cases by status
	@SuppressWarnings("unchecked")
	public  Collection <TestCase> findTestCaseByStatus( Status s ){
		Query query = entityManager.createQuery(" SELECT c FROM TestCase c WHERE c.status = :s  ");
		query.setParameter("s", s);
		return  ( Collection <TestCase> ) query.getResultList();
	}
	
	//search by creator id, name
	@SuppressWarnings("unchecked")
	public Collection <TestCase> findTestCaseByCreatorId( int cId ){
		User creator;
		try {
			creator = userBean.findUserById(cId);
		} catch (NoResultException e) {
			throw new IllegalArgumentException("no user with id '" + cId + "'");
		}
		return (Collection <TestCase>) creator.getCaseSetCreator();
	}
	
	@SuppressWarnings("unchecked")
	public Collection <TestCase> findTestCaseByCreatorName( String cName ){
		User creator = userBean.findUserByName( cName );
		return (Collection <TestCase>) creator.getCaseSetCreator();
	}
	
	@SuppressWarnings("unchecked")
	public Collection <TestCase> findTestCaseByModifierName( String mName ){
		User modifier = userBean.findUserByName( mName );
		return (Collection <TestCase>) modifier.getCaseSetModifier();
	}
	
	//search test cases by creation date and modification date
	@SuppressWarnings("unchecked")
	public Collection  <TestCase> findTestCaseByCDate( Date cDate ){
		Query query = entityManager.createQuery(" SELECT c FROM TestCase c WHERE c.creationDate = :creationDate  ");
		query.setParameter("creationDate", cDate);
		return (Collection <TestCase>) query.getResultList();
	}
	
	@SuppressWarnings("unchecked")
	public Collection <TestCase> findTestCaseByMDate( Date mDate ){
		Query query = entityManager.createQuery(" SELECT c FROM TestCase c WHERE c.creationDate = :creationDate  ");
		query.setParameter("modificationDate", mDate);
		return (Collection <TestCase>) query.getResultList();
	}
    //search for all test cases belonging to a plan, test specification or product given the name of the TC container
	
	//search test cases belonging to a product given the product name
	@SuppressWarnings("unchecked")
	public Collection <TestCase > findTestCaseByProductName( String productName ){
		Product product = productBean.findProductByName( productName );
		Set <TestCase> testCases = product.getTestCaseSet();
		return (Collection <TestCase>) testCases;
	}
	
	//search test cases belonging to a test specification given the specification summary
	@SuppressWarnings("unchecked")
	public Collection <TestCase > findTestCaseBySpecSummary( String s ){
		TestSpecification specification = specificationBean.findTestSpecBySummary(s);
		Set <TestCase> testCases = specification.getTestCaseSet();
		return (Collection <TestCase>) testCases;
	}
	
	//implement search by Test Plan after the test plan bean is implemented
	@SuppressWarnings("unchecked")
	public Collection <TestCase > findTestCaseByTestPlan( String s ){
		TestPlan plan = planBean.findTestPlanBySummary(s);
		Set <TestCase> testCases = plan.getTestCaseSet();
		return (Collection <TestCase>) testCases;
	}
}
